package role

import (
	"sanguo/cluster"
	"sanguo/node/common/attr"
	"sanguo/node/common/transaction"
	"sanguo/node/node_game"
	ss_rpc "sanguo/protocol/ss/rpc"
	"sanguo/rpc/changeOutline"
	"sanguo/rpc/enterMap"
	"sanguo/rpc/leaveMap"

	"github.com/golang/protobuf/proto"
)

/*
*注意这里是异步切换地图 处理
 */
const (
	err_ok   = 1
	err_fail = 2
)

func (this *Role) LeaveMap() {
	if this.NodeMap == nil {
		return
	}

	req := &ss_rpc.LeaveMapReq{
		MapType: proto.Int32(this.GetMapID()),
		UserID:  proto.String(this.user.GetUserID()),
	}
	leaveMap.AsynCall(*this.NodeMap, req, transaction.TransTimeoutMs, func(resp *ss_rpc.LeaveMapResp, err error) {
		if nil == err && resp.GetOk() == 1 {
			node_game.Debugln(this.user.GetUserID(), "leave old map", this.GetMapID(), "OK")
			this.SetMapID(0)
			this.NodeMap = nil
		} else {
			node_game.Debugln(this.user.GetUserID(), "leave old map", this.GetMapID(), "failed:", err, resp.GetOk())
		}
	})

}

func (this *Role) EnterMap(mapID, x, y, z, anglge int32) {
	node_map, err := cluster.Random("map")
	if nil != err {
		node_game.Debugln("no map server")
		return
	}
	if this.NodeMap != nil {
		this.LeaveMap()
	}
	storyStage, _ := this.GetRoleAttr().GetAttr(attr.StoryStage)

	req := &ss_rpc.EnterMapReq{
		MapType:    proto.Int32(mapID),
		UserID:     proto.String(this.user.GetUserID()),
		Name:       proto.String(this.GetName()),
		ID:         proto.Uint64(this.GetID()),
		Lev:        proto.Int32(this.GetLev()),
		Portrait:   proto.Int32(this.GetPortrait()),
		Face:       proto.Int32(this.GetFace()),
		Hair:       proto.Int32(this.GetHair()),
		HairColor:  proto.Int32(this.GetHairColor()),
		EyeColor:   proto.Int32(this.GetEyeColor()),
		Cloth:      proto.Int32(this.GetCloth()),
		ClothColor: proto.Int32(this.GetClothColor()),
		Weapon1:    proto.Int32(this.GetWeapon1()),
		Weapon2:    proto.Int32(this.GetWeapon2()),
		Outline:    proto.Int32(this.GetOutline()),
		Game:       proto.String(node_game.GetSelfService().ToPeerID().ToString()),
		Pos: &ss_rpc.Position{
			X: proto.Int32(x),
			Y: proto.Int32(y),
			Z: proto.Int32(z),
		},
		Angle:      proto.Int32(anglge),
		StoryStage: proto.Int64(storyStage),
	}
	enterMap.AsynCall(node_map, req, transaction.TransTimeoutMs, func(resp *ss_rpc.EnterMapResp, err error) {
		if nil == err && resp.GetOk() == 1 {
			this.SetMapID(mapID)
			this.SetPos(x, y, z)
			this.SetAngle(anglge)
			this.NodeMap = &node_map
			this.ChatChangeMap()
			node_game.Debugln(this.user.GetUserID(), "entermap", mapID, "ok")
		} else {
			node_game.Debugln(this.user.GetUserID(), "entermap", mapID, "failed:", err, resp.GetOk())
		}
	})
}

func (this *Role) ChangeOutline() {
	if this.NodeMap == nil {
		return
	}
	req := &ss_rpc.ChangeOutlineReq{
		MapType: proto.Int32(this.GetMapID()),
		UserID:  proto.String(this.user.GetUserID()),
		RoleID:  proto.Uint64(this.GetID()),
		Lev:     proto.Int32(this.GetLev()),
		Weapon1: proto.Int32(this.GetWeapon1()),
		Weapon2: proto.Int32(this.GetWeapon2()),
	}
	changeOutline.AsynCall(*this.NodeMap, req, transaction.TransTimeoutMs, func(resp *ss_rpc.ChangeOutlineResp, err error) {
		if nil == err && resp.GetOK() == 1 {
			node_game.Debugln(this.user.GetUserID(), "ChangeOuline OK")
		} else {
			node_game.Debugln(this.user.GetUserID(), "ChangeOuline failed:", err, resp.GetOK())
		}
	})
}
